package com.gopay.bis.pab.expay.operation;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathExpressionException;
import javax.xml.xpath.XPathFactory;

import org.apache.commons.lang3.StringUtils;
import org.w3c.dom.Document;
import org.xml.sax.SAXException;

import com.gopay.common.domain.bank.pab.expay.res.PabExPayFastpayFPARes;
import com.gopay.common.domain.bank.pab.expay.res.PabExPayFastpaySOQRes;
import com.gopay.common.domain.bank.pab.expay.res.PabExPayFastpaySOQResFather;
import com.gopay.common.domain.bank.pab.expay.res.PabExPayFastpaySOQResH;
import com.gopay.common.exception.GopayException;

/**
 * 
 * @ClassName: DomParseXmlUtil 
 * @Description: dom解析xml工具类
 * @author ShenJun 
 * @date 2017年2月27日 下午5:28:36
 */
public class DomParseXmlUtil {
	private static DocumentBuilder builder;
	
	private static XPath xpath;
	
	static{
		try {
			builder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
			xpath = XPathFactory.newInstance().newXPath();
		} catch (ParserConfigurationException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	
	/**
	 * 
	 * @Description: 通过dom解析xml，转成对象。（只对传入类型里面存在的属性进行赋值）
	 * @param xmlString	xml字符串
	 * @param clazz  目标类型
	 * @param path	需要转化的节点路径，如Fastpay/Message/SOQResH
	 * @return 
	 * @author ShenJun
	 * @throws GopayException 
	 */
	public static synchronized Object fromXml(String xmlString, Class clazz, String path) throws GopayException{
		//去掉xml头：" <?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>"
		xmlString = xmlString.replaceAll("<\\?[\\s\\S]+\\?>", "");
		//System.out.println(xmlString);
		Object obj = null;
		try {
			obj = clazz.newInstance();
			InputStream inputStream = new ByteArrayInputStream(xmlString.getBytes());
			Document document = builder.parse(inputStream);
			
			Field[] fields = clazz.getDeclaredFields();
			for (Field field : fields) {
				String name = field.getName();
	            String value = (String) xpath.evaluate(path + "/" + name,document, XPathConstants.STRING);
	            //System.out.println(name + "==" + value);
	            if(StringUtils.isEmpty(value)){
	            	continue;
	            }
	            String methodStr = "set"+name.toUpperCase().substring(0, 1)+name.substring(1);
	            Method method = clazz.getMethod(methodStr,new Class[]{field.getType()});
	            method.invoke(obj, value);
	            //System.out.println(name + "==" + value);
			}
			
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			throw new GopayException("DomParseXmlUtil.fromXml转换发生错误",e);
		} 
		return obj;
	}
	
	
	public static void main(String[] args) {
		for (int i = 0; i < 5; i++) {
			MyThread m = new MyThread();
			m.start();
		}
		
	}

}

class MyThread extends Thread {

	@Override
	public void run() {
		String retString = "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?><Fastpay><Message id=\"1495704823441\"><SOQRes id=\"SOQRes\"><serialNo>2017052505366649</serialNo><orderDate>20170525</orderDate><transType>1</transType><signNo>6230583000003130178</signNo><amount>0.01</amount><currency>156</currency><status>Y</status><cause>银行主机单笔代收成功！</cause><Extension/><instId>1248</instId></SOQRes><Signature xmlns=\"http://www.w3.org/2000/09/xmldsig#\"><SignedInfo><CanonicalizationMethod Algorithm=\"http://www.w3.org/TR/2001/REC-xml-c14n-20010315\"/><SignatureMethod Algorithm=\"http://www.w3.org/2000/09/xmldsig#rsa-sha1\"/><Reference URI=\"#SOQRes\"><Transforms><Transform Algorithm=\"http://www.w3.org/2000/09/xmldsig#enveloped-signature\"/></Transforms><DigestMethod Algorithm=\"http://www.w3.org/2000/09/xmldsig#sha1\"/><DigestValue>Mr/V1t2dKulZbi595y29xmuRktY=</DigestValue></Reference></SignedInfo><SignatureValue>VN7CqWZ6bdSZS7CjRut5Vg8xk/i6egGa13NoMYJ2J5nwzJHgGRNyertw21XgV3hYS6yoUYZtcM8b"
+"NC0vvvKo/+TMtjDKs+bwHw1by5rNeBEtu2rvgE12jCHV1kzWRkGNbXGtyGQm8gLdZdHSl0D6XB87"
+"DKJsVGNYKy/wvAx9fV4=</SignatureValue></Signature></Message></Fastpay> ";
		PabExPayFastpaySOQResFather res =null;
		try {
			res = (PabExPayFastpaySOQResFather)DomParseXmlUtil.fromXml(retString, PabExPayFastpaySOQResFather.class, "Fastpay/Message/SOQRes");
			System.out.println(res.getSerialNo());
			System.out.println(res.getStatus());
			
		} catch (GopayException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	
}
